home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
EMULATOR
/
GAMEBOY_DEVKIT.ZIP
/
!GBDK
/
docs
/
GBDK
< prev
next >
Wrap
Text File
|
1997-02-18
|
20KB
|
719 lines
+--------------------------------------------------------------------+
| The following is an HTML file converted into text format. See |
| http://lsewww.epfl.ch/~felber/home.html for the original. |
+--------------------------------------------------------------------+
GameBoy Developer's Kit
Version 1.1
What is the GBDK?
The name may sound pretentious. But with the GBDK, you can develop
your own programs for the GB system, either in C or in assembly. The
GBDK includes a set of libraries for the most common requirements and
generates image files for use with a real GB or with VGB.
Why making development tools for the GB?
Because the GB really is a nice system, with lots of good games. It is
small, cheap, has a good autonomy and is quite powerful. It has even a
serial port. Further more, it is not only aimed at games.
What is the GBDK composed of?
The GBDK is composed of:
* A full featured C compiler (with the only limitation that a
floating point library has yet to be written)
* An assembler that generates relocatable code
* A linker that produces GB image files
* A set of basic libraries, with source code
* Some example programs in assembly and in C
Well, I have not written all these programs from scratch.
The compiler is based on lcc, a retargetable compiler for ANSI/ISO C.
Their original version generates code for the SPARC, MIPS R3000, and
Intel 386 and its successors. lcc is in production use at Princeton
University and AT&T Bell Laboratories. The man page gives usage
details.
The assembler and the linker are based on public domain programs
developed by Alan R. Baldwin.
Which system does the GBDK run on?
The UNIX version of GBDK has been tested on Sun Solaris 2.4 and Linux.
The DOS version requires a 386 processor (or higher).
Limitations
* The C compiler is missing support for floats and doubles (the
compiler supports them, but libraries are missing. If someone
is interested in writing them...)
* The linker generates only 32kb images for the time. Generating
64kb images is not a problem, but bigger images require bank
switching.
* Do not use -0x8000 (minimum 16-bit signed integer) in
divisions. -0x7FFF is the limit.
Other sites with info on the GB
* Nintendo GameBoy Homepage
http://www.freeflight.com/fms/GameBoy/
* Jeff Frohwein's Technical Information Page
http://fly.hiwaay.net/~jfrohwei/gameboy/home.html
----------------------------------------------------------------------
Changes
Changes in version 1.1
* Removed Xloadimage from the GBDK distribution. It is now
available as a separate archive.
* A compiled DOS version is now available (cross-compiled on my
Sun Workstation!).
* The libraries and the example programs have been improved.
* The make script has been improved. Compiling on UNIX should be
easier.
* Many bugfixes.
----------------------------------------------------------------------
The Compiler
I've written a code generator for lcc that generates code for the Z80.
It does not produce optimal code, but it is usable. It took a long
time to debug, but I think it is now quite stable. Note than due to
the limitations of the Z80, sizeof(int) = sizeof(long) = 2.
For more information, read the docs included with the lcc
distribution.
The following flags allow to pass options to the assembler and to the
linker:
-Wa
-Wl
If the assembler generates an error message, you can produce an
assembly listing .lst to see where the error occurs using the flag:
-Wa-l
If you want to see the memory mop of the image file (where the
functions are located in ROM), you can produce a .map file using:
-Wl-m
----------------------------------------------------------------------
The Assembler
The GB processor is very similar to the Z80, although some of the
instructions are missing and some ther have been added. Also, she
second set of registers (BC', DE', HL', AF') and the index registers
(IX, IY) are missing and, consequently, there are no DD and FD opcode
tables. Finally, I/O ports are gone and so are all IN/OUT opcodes.
Changed instructions (from the GameBoy FAQ, by Marat Fayzullin):
08 xx xx EX AF,AF' LD (word),SP Save SP at given address
10 xx DJNZ offset STOP Meaning unknown
22 LD (word),HL LD (HLI),A Save A at (HL) and increment HL
2A LD HL,(word) LD A,(HLI) Load A from (HL) and increment HL
32 LD (word),A LD (HLD),A Save A at (HL) and decrement HL
3A LD A,(word) LD A,(HLD) Load A from (HL) and decrement HL
D3 OUTA (byte) No operation
D9 EXX RETI Enable interrupts and return
DB INA (byte) No operation
DD Prefix DD No operation
E0 xx RET PO LD (byte),A Save A at (FF00+byte)
E2 JP PO,word LD (C),A Save A at (FF00+C)
E3 EX HL,(SP) No operation
E4 CALL PO,word No operation
E8 xx RET PE ADD SP,offset Add signed offset to SP
EA xx xx JP PE,word LD (word),A Save A at given address
EB EX DE,HL No operation
EC CALL PE,word No operation
F0 xx RET P LD A,(byte) Load A from (FF00+byte)
F2 JP P,word No operation
F4 CALL P,word No operation
F8 xx RET M LDHL SP,offset Load HL with SP + signed offset
FA xx xx JP M,word LD A,(word) Load A from given address
FC CALL M,word No operation
FD Prefix FD No operation
I have also modified the name of some of the GB-specific opcodes:
LD (HLI),A -> LD (HL+),A
LD (HLD),A -> LD A,(HL-)
LD A,(HLI) -> LD (HL+),A
LD A,(HLD) -> LD A,(HL-)
ADD SP,offset -> LDA SP,offset(SP)
LDHL SP,offset -> LDA HL,offset(SP)
The LDA opcode means "load address", like in 68x00 assembly. I've
called these instructions like this because both are orthogonal (they
do the same thing on two different registers), and anyway I hate the
LDHL (just because the destination register is specified in the
opcode).
The assembler accepts the following flags:
Usage: [-vdqxcgalosf] [-n filename] file1 [file2 file3 ...]
v verbose
d decimal listing
q octal listing
x hex listing (default)
k case sensitive
g undefined symbols made global
a all user symbols made global
l create list output file[LST]
o create object output file[O]
s create symbol output file[SYM]
f flag relocatable references by ` in listing file
ff flag relocatable references by mode in listing file
n name of output files (for following input file)
For more information, read the asmlnk.doc file in the doc directory.
----------------------------------------------------------------------
The Linker
The linker accepts the following flags:
Usage: [-options] -o outfile [file.o ... | @file.lst]
@file.lst file with list of files to link, separated by newlines
-c case sensitive
-v verbose
Relocation:
-b area base address = expression
-g global symbol = expression
Map format:
-m map output generated as file[MAP]
-x hexidecimal (default)
-d decimal
-q octal
Output:
-i Intel hex as file[IHX]
-s Motorola s19 as file[S19]
-z Gameboy image as file[GB]
For more information, read the asmlnk.doc file in the doc directory.
----------------------------------------------------------------------
The Libraries
Three libraries are included in the GBDK. Their functions are
described in details below.
crt0.o
Basic C runtime, with GB initialization routines, C support (mul, div,
mod) and other essential things. This library is automatically linked
with every program.
terminal.o - stdio.o
Libraries for basic text input/output. Implements standard functions
from stdio, ctype and string.
drawing.o
Very primitive graphic library that allows to draw points to the
screen, and to display images. The drawing area is limited because of
the way the GB handles display.
----------------------------------------------------------------------
stdlib.o
Include files
* stdlib.h
Source files
* crt0.s
Functions
void mode(int m);
Change current working mode (M_DRAWING or M_TEXT). This is
normally implicitly done when using library functions.
void delay(int d);
Small pause.
void pause(int p);
Longer pause.
int joypad();
Read the joypad status. Joypad keys are J_START, J_SELECT,
J_B, J_A, J_DOWN, J_UP, J_LEFT and J_RIGHT.
int waitpad(int mask);
Wait for one of the specified joypad keys to be pressed.
void waitpadup();
Wait for the joypad to be released.
void enable_interrupts();
void disable_interrupts();
Enable or Disable interrupts (must be enabled for
displaying sprites).
void display_on();
void display_off();
Switch screen on or off.
void show_bkg();
void hide_bkg();
Show or hide the background display.
void set_bkg_data(int first_tile, int nb_tiles, unsigned char *data);
Set the data of part of the background tiles.
-128 <= first_tile <= 127
-128 <= first_tile+nb_tiles <= 127
nb_tiles >= 1
void set_bkg_tiles(int x, int y, int w, int h, unsigned char *tilelist);
Set the tile number of part of the background.
0 <= x <= 31
0 <= y <= 31
1 <= w <= 32-x
1 <= h <= 32-y
void scroll_bkg(int x, int y);
Scroll the background (relative to current position).
void show_window();
void hide_window();
Show or hide the window display.
void show_sprites();
void hide_sprites();
Show or hide the sprites display.
void sprites8x8();
void sprites8x16();
Set the size of all sprites.
void set_sprite_data(int first_tile, int nb_tiles, unsigned char *data);
Set the data of part of the sprite tiles.
0 <= first_tile <= 255
0 <= first_tile+nb_tiles <= 255
nb_tiles >= 1
void set_sprite_tile(int nb, int tile);
Set the tile number of a sprite.
0 <= nb <= 39
0 <= tile <= 255
void set_sprite_prop(int nb, int prop);
Set the properties of a sprite. Sprite properties bits are
S_PALETTE, S_FLIPX, S_FLIPY and S_PRIORITY.
0 <= nb <= 39
void move_sprite(int nb, int x, int y);
Change the position of a sprite.
0 <= nb <= 39
0 <= x <= 255
0 <= y <= 255
----------------------------------------------------------------------
stdio.o - terminal.o
Include files
* stdio.h
Source files
* stdio.c
* terminal.s
Functions
int atoi(char *s);
Return the integer value of a numeric string.
int abs(int num);
Return the absolute value of an integer.
int isalpha(char c);
int isupper(char c);
int islower(char c);
int isdigit(char c);
int isspace(char c);
Functions that classify character-coded integer values.
int toupper(char c);
int tolower(char c);
Change character case
int index(char *s, char *t);
Find index of string t in s.
char *itoa(int n, char *s);
Transform an integer in its ascii representation.
void printn(int number, int radix);
Print a number in any radix.
char *reverse(char *s);
Reverse a character string.
char *strcat(char *s1, char *s2);
Concatenate s2 on the end of s1. s1 must be large enough.
Return s1.
int strcmp(char *s1, char *s2);
Compare strings:
s1>s2: >0
s1==s2: 0
s1<s2: <0
char *strcpy(char *s1, char *s2);
Copy string s2 to s1. s1 must be large enough. Return s1.
int strlen(char *s);
Return length of string.
char *strncat(char *s1, char *s2, int n);
Concatenate s2 on the end of s1. s1 must be large enough.
At most n characters are moved. Return s1.
int strncmp(char *s1, char *s2, int n);
Compare strings (at most n bytes):
s1>s2: >0
s1==s2: 0
s1<s2: <0
char *strncpy(char *s1, char *s2, int n);
Copy s2 to s1, truncating or null-padding to always copy n
bytes. Return s1.
void puts(char *str);
Print a string with a carriage return.
void print(char *str);
Print a string without carriage return.
void printf(char *fmt, ...);
int scanf(char *fmt, ...);
Print a fromatted string. printf and scanf support the
following types:
%c char
%d decimal int
%o octal int
%p pointer
%s string
%x hexadecimal int
When waiting for a user input, a kind of keyboard appears at the
bottom of the screen, which allows to enter characters. The
following buttons are used:
Arrow keys: Move the cursor
A: Enter a character
B: Delete a character
START: End of line (carriage return)
SELECT: Temporarily hide the keyboard
void putchar(char c);
Print a character.
char getchar();
Read a character.
char *gets(char *s);
Read a string.
void gotoxy(int x, int y);
Move the cursor to a specific position
int posx();
int posy();
Return the current cursor position
void setchar(char c);
Set the character at cursor position, without character
interpretation ('\n' does not move to the next line) and
without moving the cursor.
----------------------------------------------------------------------
drawing.o
Include files
* graphics.h
Source files
* drawing.s
Functions
void plot(int x, int y, int color, int mode);
Draw a pixel on screen with specific color and mode.
Colors are WHITE, LTGREY, DKGREY and BLACK. Modes are AND,
OR, XOR and SOLID.
void draw_image(unsigned char *data);
Draws a complete image to screen. Image size must be
0x80 * 0x78 pixels.
----------------------------------------------------------------------
The Test and Example Programs
The test programs are located in the tst directory. Most of them are
taken from the lcc distribution. Expected output are located in the
.out files.
8q.c
The classic 8 queens problem (place 8 queens on a
chessboard so that none of them threaten the others).
array.c
Test program with arrays.
init.c
Test program with variable initializations.
sort.c
Sorting algorithm that uses arrays and pointers.
struct.c
Test program with structures.
test.c
Test program for terminal and drawing libraries.
There are also three interesting sample programs in the examples
directory:
space.s
Assembly program that demonstrates the use of sprites,
window, background, fixed-point values and more. The
following keys are used:
Arrow keys: Change the speed (and direction) of the sprite
Arrow keys+A: Change the speed (and direction) of the window
Arrow keys+B: Change the speed (and direction) of the
background
START: Open/close the door
SELECT: Basic fading effect
sound.c
Program for experimenting with the soung generator of the
GB (to use on a real GB). The four different sound modes
of the GB are available. It also demonstrates the use of
bit fields in C (it's a quick hack, so don't expect too
much from the code). The following keys are used:
UP/DOWN: Move the cursor
RIGHT/LEFT: Increment/decrement the value
RIGHT/LEFT+A: Increment/decrement the value by 10
RIGHT/LEFT+B: Set the value to maximum/minimum
START: Play the current mode's sound (or all modes if in
control screen)
START+A: Play a little music with the current mode's sound
SELECT: Change the sound mode (1, 2, 3, 4 and control)
SELECT+A: Dump the sound registers to the screen
sprite.c
Program that demonstrates the use of sprinte form C.
rpn.c
Basic RPN calculator. Try entering expressions like 12
134* and then 1789+.
----------------------------------------------------------------------
Mixing C and Assembly
For mixing C and assembly, you must use different files (you cannot
embed C code with assembly) and link them together. Here are the
things you must know:
* A C identifier i will be called _i in assembly
* Results are always returned into the HL register
* Parameters are always passed on the stack (starting at SP+2
because the return address is also saved on the stack)
* Assembly identifier are exported using the .globl directive
* You can access GameBoy hardware registers using _reg_XX where
XX is the register number (see sound.c for an real example)
* Registers must be preserved across function calls (you must
store them at function begin, and restore them at the end),
except HL.
Here is an example of how to mix assembly with C:
main.c
main()
{
int i;
int add(int, int);
i = add(1, 3);
}
add.s
.globl _add
_add: ; int add(int a, int b)
PUSH BC ; Save used registers (except HL)
PUSH DE
LDA HL,2(SP)
LD C,(HL) ; Get a
INC HL
LD B,(HL)
INC HL
LD E,(HL) ; Get b
INC HL
LD D,(HL)
LD H,D ; Move DE into HL
LD L,E
ADD HL,BC ; Add BC to HL
POP DE ; Restore registers
POP BC
RET ; Return result into HL
----------------------------------------------------------------------
Troubleshooting
Errors
Messages of the type:
u 0226
a 0329
u 0333
are error messages from the assembler. To see where these errors
occur, you should produce an assembly listing using the -Wa-l flag of
lcc. An object file is generated, but must be corrupted. For more
information on the different types of errors, read the asmlnk.doc file
in the doc directory.
Messages of the type:
?ASlink-W-Undefined Global .count referenced by module Demo
are error messages from the linker. You probably forgot a library when
linking, An image file is generated, but must be corrupted.
Warnings
* Do not declare initialized variables at the file level, except
when they are read-only, because they will be located in ROM,
e.g.
int i1; /* OK : will be located in RAM */
char *s1; /* OK : will be located in RAM */
int i2 = 0; /* Error : will be located in ROM */
char *s2 = "Hi"; /* Error : will be located in ROM */
void main() { ... }
* Both terminal.o and drawing.o libraries use a lot of tiles and
sprites from the GB. You should not use your own tiles or
sprites with these libraries.
* If you use both libraries in a same program, keep in mind that
there will be a "mode switch" when using a function from a
library after one of the other and all your work will be lost
(if in drawing mode you use a terminal function, your drawing
will be lost).
----------------------------------------------------------------------
For suggestions, comments, bug reports... please mail to <felber@di.epfl.ch>.
----------------------------------------------------------------------
Last change: January 9, 1997